home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 49 / Amiga Format CD49 (2000-01-17)(Future Publishing)(GB)(Track 1 of 3)[!][issue 2000-02].iso / -serious- / misc / charmap / source / cmap.c < prev    next >
C/C++ Source or Header  |  1999-11-30  |  14KB  |  433 lines

  1. /******************************************************************
  2. ** charmap.c : Affiche la table ascii d'une police de caractère  **
  3. **             Écrit (en partie) par T.Pierron                   **
  4. **             14-11-1999                                        **
  5. **---------------------------------------------------------------**
  6. ** Special Requirements: WorkBench 2.0, version 36 or above      **
  7. ******************************************************************/
  8.  
  9. #include <Intuition/Intuition.H>
  10. #include <Intuition/IntuitionBase.H>
  11. #include <Graphics/RastPort.H>
  12. #include <Graphics/Text.H>
  13. #include <Libraries/Gadtools.H>
  14. #include <Intuition/Screens.H>
  15.  
  16. #include "cmap.h"
  17. #define  CATCOMP_NUMBERS        /* We will need the string id */
  18. #define  CATCOMP_STRINGS        /* and the english string corresponding to this id */
  19. #include "cmap_strings.h"
  20.  
  21. /* Shared libraries we'll need to open */
  22. struct IntuitionBase *IntuitionBase = NULL;
  23. struct GfxBase *GfxBase       = NULL;
  24. struct Library *GadToolsBase  = NULL;
  25. struct Library *AslBase       = NULL;
  26. struct Library *DiskfontBase  = NULL;
  27. struct Library *CxBase            = NULL;
  28. struct Library *IconBase        = NULL;
  29. struct Library *KeymapBase        = NULL;
  30. struct Library *LocaleBase    = NULL;
  31. void           *clipdev            = NULL;
  32.  
  33. /* Graphics area: */
  34. struct RastPort *RP,RPT;
  35. struct TextFont *font,*newfont=0;
  36.  
  37. struct Menu   *menu   = NULL;                /* Menu attached to the window */
  38. struct Screen *screen = NULL;                /* Screen where window will be opened */
  39. struct Window *window = NULL;                /* Main window ptr */
  40. struct Gadget *glist  = NULL;             /* Gadget list pointer */
  41. struct Gadget *gad;                            /* our running Gadget pointer */
  42. void   *vi = NULL;                            /* VisualInfo pointer */
  43.  
  44. WORD  ZoomData[4];                            /* Position of iconified window */
  45. WORD  xdeb,ydeb,xfin,yfin,X,Y;            /* Position of ASCII table */
  46. UBYTE CharWid[256],Char[]=" ";            /* Data of ASCII table */
  47. UBYTE Font_height;                            /* Font information */
  48. UBYTE GadDisable=0;                            /* If ressource unavailable */
  49.  
  50. /* For the "version" command: */
  51. const UBYTE VERSION[]= "$VER:CharMap v" CHARMAP_VERSION " 14/11/1999\n";
  52.  
  53. /* Tag list for openning the main window: */
  54. ULONG WinTags[] = {
  55.     WA_Zoom,(ULONG)ZoomData,
  56.     WA_NewLookMenus,TRUE,
  57.     TAG_DONE
  58. };
  59.  
  60. /* For our string gadget: */
  61. ULONG StrTags[] = {
  62.     GTST_MaxChars,50,
  63.     TAG_DONE
  64. };
  65.  
  66. /* Set the color of the menu to Newlook (only 3.0+): */
  67. ULONG MenuTags[] = {
  68.     GTMN_FrontPen, 1,
  69.     TAG_DONE
  70. };
  71.  
  72. ULONG BoxTags[] = {
  73.     GT_VisualInfo,0,
  74.     TAG_DONE,FALSE,
  75.     TAG_DONE
  76. };
  77.  
  78. /* Our gadtools gadgets text: */
  79. UBYTE *GadTxt[]={
  80.     MSG_STRGAD_STR,
  81.     MSG_COPY_STR,
  82.     MSG_PASTE_STR,
  83.     MSG_CLEAR_STR,
  84.     MSG_NEWFONT_STR
  85. };
  86.  
  87. /* here we declare the information for our new window - notice that GadTools
  88.  * provides some constants which describe which IDCMP events the Window will
  89.  * need to handle the GadTools Gadgets properly. Just OR them into your
  90.  * normal IDCMPFlags field.
  91.  */
  92.  
  93. ULONG sigwin=0;
  94. struct NewWindow new_window = {
  95.     50, 20, 510, 150,
  96.     -1, -1,                        /* DetailPen, BlockPen */
  97.     CLOSEWINDOW | REFRESHWINDOW | MOUSEBUTTONS | MOUSEMOVE | RAWKEY | MENUPICK | MENUVERIFY | GADGETUP,
  98.     ACTIVATE | WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE | SMART_REFRESH | REPORTMOUSE,
  99.     NULL,                            /* FirstGadget */
  100.     NULL,                            /* CheckMark */
  101.     MSG_WINTITLE_STR,
  102.     NULL,                            /* Screen */
  103.     NULL,                            /* BitMap */
  104.     0, 0, 0, 0,                    /* min/max sizes */
  105.     CUSTOMSCREEN
  106. };
  107.  
  108. /* Error messages: */
  109. UBYTE *Errors[]= {
  110.     MSG_BADOS_STR,
  111.     MSG_SCREENLOCK_STR,
  112.     MSG_ERRMENUBAR_STR,
  113.     MSG_ERRLAYOUT_STR,
  114.     MSG_FONTTOOBIG_STR,
  115.     MSG_ERRGADGET_STR
  116. };
  117. #define ErrMsg(num)        Errors[ num-MSG_BADOS ]
  118.  
  119. struct EasyStruct Request=
  120. { sizeof(struct EasyStruct),0,
  121.   MSG_ABOUT_STR,
  122.   MSG_ABOUTMSG_STR,
  123.   MSG_CONTINUE_STR
  124. };
  125.  
  126. /**********************************************************
  127. *****                    MENU DATA MANAGMENT:                        *****
  128. **********************************************************/
  129.  
  130. /* NewMenu menu declaration */
  131. struct NewMenu newmenu[] =
  132. {
  133.     {NM_TITLE, MSG_MENUTITLE_STR,0 , 0, 0, 0},
  134.     {  NM_ITEM, MSG_MENUFONTSCREEN_STR,"S", CHECKIT|CHECKED, ~1, (APTR) 11},
  135.     {  NM_ITEM, MSG_MENUTEXTFONT_STR,  "T", CHECKIT, ~2, (APTR)12},
  136.     {  NM_ITEM, MSG_MENUCUSTOMFONT_STR,"F", CHECKIT, ~4, (APTR)13},
  137.     {  NM_ITEM, NM_BARLABEL,  0, 0, 0, 0},
  138.     {  NM_ITEM, MSG_MENUCHARSET_STR,   0, 0, 0, 0},
  139.     {   NM_SUB,   MSG_MENUASCII8_STR,    "1", CHECKIT, ~1, (APTR)141},
  140.     {   NM_SUB,   MSG_MENUISOLATIN1_STR, "2", CHECKIT|CHECKED, ~2, (APTR)142},
  141.     {   NM_SUB,   MSG_MENUSTDAMIGA_STR,  "3", CHECKIT, ~4, (APTR)143},
  142.     {  NM_ITEM, MSG_MENUCLEARTXT_STR,  "Del", NM_COMMANDSTRING, 0, (APTR)14},
  143.     {  NM_ITEM, MSG_NEXTSCR_STR,         "J", 0, 0, (APTR)15},
  144.     {  NM_ITEM, MSG_MENUABOUT_STR,       "?", 0, 0, (APTR)16},
  145.     {  NM_ITEM, NM_BARLABEL,  0 , 0,  0, 0},
  146.     {  NM_ITEM, MSG_MENUICONOFY_STR,     "I", 0, 0, (APTR)17},
  147.     {  NM_ITEM, MSG_MENUHIDE_STR,        "H", 0, 0, (APTR)18},
  148.     {  NM_ITEM, MSG_MENUQUIT_STR,        "Q", 0, 0, (APTR)19},
  149.    {NM_END, 0, 0, 0, 0, 0},
  150. },*checked=&newmenu[1],
  151.   *checkset=&newmenu[7];
  152.  
  153. /* Different width of box for each charset: */
  154. UBYTE MaxWid,NumChars;
  155. UBYTE CharsetNum=2;
  156.  
  157. /* Colors pens: */
  158. UWORD fillpen=3,txtpen=1,poppen=2,filltxt=2;
  159.  
  160. /* Function prototypes */
  161. BYTE setup();                                        /* Open window, ressources, font... */
  162. void cleanup(UBYTE *,WORD);                    /* Quit properly */
  163. void create_gadgets(void);                        /* Create the gadget using gadtools lib */
  164. void handle_input(void);                        /* Handle intuition events */
  165. void Init_helpwin();                                /* Alloc memory for help window */
  166. void Open_helpwin(UBYTE, WORD, WORD);        /* Show the help window */
  167. void Free_helpwin();                                /* Free all allocated memory */
  168. void Close_helpwin();                            /* Cleanup the display */
  169.  
  170. /**** Definition of the main loop: ****/
  171. int main(int argc, char *argv[])
  172. {
  173.     extern BOOL PopWin;                                    /* True if the window is poped up at start */
  174.  
  175.     /* Open ze libraries */
  176.     if( (CxBase   = (void *) OpenLibrary("commodities.library", 37L)) &&
  177.          (IconBase = (void *) OpenLibrary("icon.library",        36L)) )
  178.         /* If the icon and commodities.library are present, and the    **
  179.         ** programm failed to init as a commodity, it's probably        **
  180.         ** because it is already running, and user want to quit:        */
  181.     {    if( Init_commodity(argc,argv)==FALSE )
  182.             cleanup(0,0);
  183.     } else
  184.         newmenu[14].nm_Flags |= NM_ITEMDISABLED;    /* If no commo., can't hide the interface */
  185.  
  186.     /* These libraries are located in ROM. If it failed to open, it's  **
  187.     ** because we are attempting to run this porgramm on an old system */
  188.     if( !(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", MIN_VERSION)) ||
  189.         !(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",MIN_VERSION)) ||
  190.         !(GadToolsBase = (struct Library *)OpenLibrary("gadtools.library",MIN_VERSION)) ||
  191.         !(KeymapBase = (struct Library *)OpenLibrary("keymap.library",37)) )
  192.         cleanup(ErrMsg(MSG_BADOS),30);
  193.  
  194.     /* If no locale, use english as default: */
  195.     if(LocaleBase = (struct Library *)OpenLibrary("locale.library", 38))
  196.         Translate_srings();
  197.  
  198.     /* No ASL or diskfont libraries, no ASL font requester */
  199.     if( !(AslBase = (struct Library *)OpenLibrary("asl.library",MIN_VERSION)) ||
  200.         !(DiskfontBase  = (struct Library *)OpenLibrary("diskfont.library",0)) ) {
  201.         newmenu[3].nm_Flags |= NM_ITEMDISABLED;
  202.         GadDisable |= 8;
  203.     }
  204.  
  205.     /* For temporary font measurement: */
  206.     InitRastPort( &RPT );
  207.     /* get access to the WorkBench screen */
  208.     screen = (struct Screen *) IntuitionBase->ActiveScreen;
  209.     font = screen->RastPort.Font;
  210.     Init_charset(font);
  211.  
  212.     if(PopWin)
  213.         /* If setup failed at start (font too big): */
  214.         if(setup()) Handle_menu(13L);
  215.  
  216.     handle_input();
  217. }
  218.  
  219. /**** Setup the window, return 1 if init failed: ****/
  220. BYTE setup()
  221. {
  222.     struct DrawInfo *di;
  223.  
  224.     /* get the screen's visual information data */
  225.     if( !(vi = (void *) GetVisualInfoA( screen,NULL )) )
  226.         cleanup(ErrMsg(MSG_SCREENLOCK),30);
  227.  
  228.     BoxTags[1]=(ULONG)vi;
  229.  
  230.     /* Adjust the pen number to what the screen uses: */
  231.     if( di = (void *)GetScreenDrawInfo(screen))
  232.     {
  233.         /* Get a copy of the correct pens for the screen: */
  234.         fillpen = di->dri_Pens[FILLPEN];
  235.         txtpen  = di->dri_Pens[TEXTPEN];
  236.         filltxt = poppen = di->dri_Pens[FILLTEXTPEN];
  237.         if(poppen==txtpen) poppen=fillpen;
  238.  
  239.         /* This one is only available on system V39+: */
  240.         if(di->dri_Version>=2) MenuTags[1] = di->dri_Pens[BARDETAILPEN];
  241.         FreeScreenDrawInfo(screen,di);
  242.     }
  243.  
  244.     /* Build the menu-strip */
  245.     if( !(menu = (void *) CreateMenusA(newmenu, MenuTags)) )
  246.       cleanup(ErrMsg(MSG_ERRMENUBAR),30);
  247.  
  248.    /* Compute the size of the menus: */
  249.    if( !LayoutMenusA(menu, vi, NULL))
  250.       cleanup(ErrMsg(MSG_ERRLAYOUT),30);
  251.  
  252.     SetFont(&RPT,font);
  253.     /* Read the size of the 256 characters of the current font, **
  254.     ** and compute the maximal width of the box chars:          */
  255.     NumChars = CharsetNum==1 ? 32 : CharsetNum == 2 ? 28 : 24;
  256.     {
  257.         register WORD I;
  258.         register UBYTE *W;
  259.         for(I=0,W=CharWid,MaxWid=0; I<256; I++,W++) {
  260.             *Char = I;
  261.             *W = TextLength(&RPT,Char,1);
  262.  
  263.             /* Compute the width of each box: */
  264.             switch( CharsetNum )
  265.             {
  266.                 case 3: if(I>=128 && I<160) break;
  267.                 case 2: if(I<32) break;
  268.                 case 1: if(MaxWid < *W+6) MaxWid=*W+6;
  269.             }
  270.         }
  271.     }
  272.  
  273.     Font_height = font->tf_YSize+4;
  274.     /* Compute the exact size of our window: */
  275.     new_window.Width  = xfin = MaxWid*NumChars+20;
  276.     new_window.Height = Font_height*8+3*screen->Font->ta_YSize+35;
  277.     new_window.Screen = screen;
  278.     new_window.LeftEdge = 50;
  279.     if(xfin+50 > screen->Width)
  280.         new_window.LeftEdge = screen->Width-xfin>>1;
  281.  
  282.     /* Init the position and the size of the iconified window: */
  283.     ZoomData[0] = 50;
  284.     ZoomData[1] = 50;
  285.     ZoomData[2] = TextLength(&screen->RastPort,new_window.Title,strlen(new_window.Title))+100;
  286.     ZoomData[3] = screen->BarHeight+1;
  287.  
  288.     /* Does the window fit in the screen? */
  289.     if( !(window = (void *) OpenWindowTagList(&new_window,WinTags)) )
  290.         /* If ASL is avaible, show a requester to change the font: */
  291.         if( avert(ErrMsg(MSG_FONTTOOBIG)) && AslBase )
  292.             return TRUE;
  293.         else cleanup(0,0);
  294.  
  295.     /* Signal bit, to process events from the window: */
  296.     sigwin = 1 << window->UserPort->mp_SigBit;
  297.    SetMenuStrip(window, menu);    /* Attach the menu to the window */
  298.    create_gadgets();                    /* Creates all gadgets */
  299.     Init_helpwin();                    /* Init the help win, using width height of the current font: */
  300.    return FALSE;
  301. }
  302.  
  303. /**** Desallocate all ressources: ****/
  304. void cleanup(UBYTE *msg,WORD err)
  305. {
  306.     extern APTR FR;
  307.     extern void *catalog;
  308.  
  309.     if (msg)            puts(msg);
  310.     if (window)    {
  311.         ClearMenuStrip(window);
  312.         CloseWindow(window);
  313.         window=NULL;
  314.     }
  315.  
  316.     /* These two functions can take a NULL, but let's stay consistent */
  317.     if (glist) FreeGadgets(glist);    glist=0;
  318.     if (vi) FreeVisualInfo(vi);        vi=0;
  319.     if (menu) FreeMenus(menu);            menu=0;
  320.     Free_helpwin();
  321.  
  322.     if (err<0) return;
  323.     Free_commodity();
  324.     if (FR)                    FreeAslRequest(FR);
  325.     if (newfont)            CloseFont(newfont);
  326.     if (catalog)            CloseCatalog(catalog);
  327.     if (clipdev)            CBClose(clipdev);
  328.     if (CxBase)                CloseLibrary(CxBase);
  329.     if (AslBase)            CloseLibrary(AslBase);
  330.     if (IconBase)            CloseLibrary(IconBase);
  331.     if (KeymapBase)        CloseLibrary(KeymapBase);
  332.     if (LocaleBase)        CloseLibrary(LocaleBase);
  333.     if (DiskfontBase)        CloseLibrary(DiskfontBase);
  334.     if (GadToolsBase)        CloseLibrary(GadToolsBase);
  335.     if (IntuitionBase)    CloseLibrary(IntuitionBase);
  336.     if (GfxBase)            CloseLibrary(GfxBase);
  337.     exit(err);
  338. }
  339.  
  340. /**** Draw the table of characters: ****/
  341. void Draw_ASCIIChart()
  342. {
  343.     register WORD i,x,y;
  344.  
  345.     /* Initial bevel box, which will be copied 256 times: */
  346.     DrawBevelBoxA(RP,xdeb,ydeb,MaxWid,Font_height,BoxTags);
  347.  
  348.     /* Exponential copy (very fast :-) */
  349.     for(x=MaxWid,i=xdeb+x,y=window->Width-10; i<xfin; ) {
  350.         ClipBlit(RP,xdeb,ydeb,RP,i,ydeb,x,Font_height,0xC0);
  351.         i+=x; x<<=1; if(i+x>y) x=y-i;
  352.     }
  353.  
  354.     for(x=Font_height,i=ydeb+x; i<yfin; i+=x,x<<=1)
  355.         ClipBlit(RP,xdeb,ydeb,RP,xdeb,i,y,x,0xC0);
  356.  
  357.     /* Character in each box: */
  358.     SetAPen(RP,txtpen);
  359.     for(i=CharsetNum==1?0:32,x=xdeb; i<256; i++,y+=Font_height)
  360.     {
  361.         if( (i&7)==0 ) { y=ydeb; x+=MaxWid; }
  362.         if( CharsetNum==3 && i==128) i=160;
  363.         *Char = i;
  364.         Move(RP,x-(MaxWid+CharWid[i]>>1),y+font->tf_Baseline+2);
  365.         Text(RP,Char,1);
  366.     }
  367. }
  368.  
  369. /**** Create the gadgets of the window: ****/
  370. void create_gadgets()
  371. {
  372. #    define tmpgad        ((struct Gadget *)RP)
  373.     struct NewGadget ng={65,5,0,14,0,0,0,PLACETEXT_LEFT | NG_HIGHLABEL,0,0};
  374.     extern UBYTE  *StrBuf;
  375.     UWORD  top,I,W;
  376.  
  377.     top = window->BorderTop + 1;
  378.     gad = (void *) CreateContext(&glist);
  379.     RP = &screen->RastPort;
  380.  
  381.     /*    the NewGadget stucture is not modified by any Gadget creation call,
  382.         so you'll only need to change information that actually needs to be
  383.         changed */
  384.     ng.ng_GadgetText = GadTxt[0];
  385.     ng.ng_TextAttr = screen->Font;
  386.     ng.ng_Width = window->Width - 10 -
  387.                       (ng.ng_LeftEdge = TextLength(RP,GadTxt[0],strlen(GadTxt[0]))+20);
  388.     ng.ng_Height = screen->Font->ta_YSize+6;
  389.     ng.ng_VisualInfo = vi;
  390.     ng.ng_TopEdge += top;
  391.  
  392.     tmpgad = gad = (void *) CreateGadgetA(STRING_KIND, gad, &ng, StrTags);
  393.  
  394.     /* Show the name of the font in the string gadget: */
  395.     StrBuf = sti(gad)->Buffer;
  396.     strcpy(StrBuf,font->tf_Message.mn_Node.ln_Name);
  397.  
  398.     /* Create the 4 gadgets shorcut: */
  399.     ng.ng_Width = W = (ng.ng_Width - 30) / 4;
  400.     ng.ng_Height -= 2;
  401.     ng.ng_Flags = PLACETEXT_IN;
  402.     top = (ng.ng_TopEdge += ng.ng_Height+5);
  403.     for(I=0,W+=10; I<4; ng.ng_LeftEdge+=W)
  404.     {
  405.         ng.ng_GadgetID   = ++I;
  406.         ng.ng_GadgetText = GadTxt[I];
  407.         tmpgad = (void *) CreateGadgetA(BUTTON_KIND, tmpgad, &ng, NULL);
  408.  
  409.         /* If a ressource isn't available, disable the corresponding gadget: */
  410.         if(GadDisable & (1<<I-1)) tmpgad->Flags |= GADGDISABLED;
  411.     }
  412.  
  413.     /*    Now we're ready to add the Gadget list. Quit if the final Gadget
  414.         pointer is NULL - this means that one of the Gadget allocations failed.
  415.         If it exists, add it to the window and refresh, then add the new
  416.         GT_RefreshWindow() call. */
  417.  
  418.     if (!tmpgad)
  419.         cleanup(ErrMsg(MSG_ERRGADGET),30);
  420.  
  421.     AddGList(window, glist, (UWORD)-1, (UWORD)-1, NULL);
  422.     RefreshGList(glist, window, NULL, (UWORD)-1);
  423.     GT_RefreshWindow(window, NULL);
  424.     RP=window->RPort;
  425.     SetFont(RP,font);
  426.     SetDrMd(RP,JAM1);
  427.  
  428.     /* Create the ASCII table: */
  429.     xdeb = 10;            ydeb = top+ng.ng_Height+5;
  430.     xfin -= 10;            yfin  = ydeb+Font_height*8;
  431.     Draw_ASCIIChart();
  432. }
  433.